
#include "giscoreao_asynprotocol.h"

#include "c2cent/library/log/CWTimeElf3.h"
#include "erp/gis/comm/erp_gis_define.h"
#include "erp/gis/comm/erp_gis_func_define.h"

using namespace erp::gis::comm;
using namespace erp::gis::ao;

using namespace c2cent::library::wwlog;
using namespace c2cent::library::wtimeelf;

enum Channel_External_Itil
{
	SOSO_GISMAP_REQ 				=  647683,
	SOSO_GISMAP_ERR 				=  647684,
	SOSO_GISMAP_RSP 				=  0,
	SOSO_GISMAP_DEF 				=  647685,
	SOSO2_GISMAP_REQ 				=  647686,
	SOSO2_GISMAP_ERR 				=  647687,
	SOSO2_GISMAP_RSP 				=  0,
	SOSO2_GISMAP_DEF 				=  647688,
	BAIDU_GISMAP_REQ 				=  647689,
	BAIDU_GISMAP_ERR 				=  647690,
	BAIDU_GISMAP_RSP 				=  0,
	BAIDU_GISMAP_DEF 				=  647691,
	GOOGLE_GISMAP_REQ 				=  647692,
	GOOGLE_GISMAP_ERR 				=  647693,
	GOOGLE_GISMAP_RSP 				=  0,
	GOOGLE_GISMAP_DEF 				=  647694,
	ALIYUN_GISMAP_REQ 				=  647695,
	ALIYUN_GISMAP_ERR 				=  647696,
	ALIYUN_GISMAP_RSP 				=  0,
	ALIYUN_GISMAP_DEF 				=  647697,
	GAODE_GISMAP_REQ 				=  647698,
	GAODE_GISMAP_ERR 				=  647699,
	GAODE_GISMAP_RSP 				=  0,
	GAODE_GISMAP_DEF 				=  647700,
};

std::string CGisMapGatewayAsynProtocol::m_strLogModule = "ao_gis_core";

CGisMapGatewayAsynProtocol::CGisMapGatewayAsynProtocol(
		const std::string& strParentName,
		const uint32_t dwDefTime,
		const uint32_t dwAlarmThreshold,
		const uint32_t dwCloseThreshold,
		const uint32_t dwCloseDuration,
		const uint32_t dwApiType,
		const bool bOpen,
		const bool bDump):
		CAsynProtocol(strParentName,dwAlarmThreshold,dwCloseThreshold,dwCloseDuration,dwApiType, bOpen,bDump)
{
	m_dwSysErrNum = 0;
	m_dwCloseTime = 0;
	
	CItilGroup oSosoItilGroup(SOSO_GISMAP_REQ, SOSO_GISMAP_ERR, SOSO_GISMAP_RSP, SOSO_GISMAP_DEF, dwDefTime);
	CItilGroup oSoso2ItilGroup(SOSO2_GISMAP_REQ, SOSO2_GISMAP_ERR, SOSO2_GISMAP_RSP, SOSO2_GISMAP_DEF, dwDefTime);
	CItilGroup oAliyunItilGroup(ALIYUN_GISMAP_REQ, ALIYUN_GISMAP_ERR, ALIYUN_GISMAP_RSP, ALIYUN_GISMAP_DEF, dwDefTime);
	CItilGroup oBaiduItilGroup(BAIDU_GISMAP_REQ, BAIDU_GISMAP_ERR, BAIDU_GISMAP_RSP, BAIDU_GISMAP_DEF, dwDefTime);
	CItilGroup oGoogleItilGroup(GOOGLE_GISMAP_REQ, GOOGLE_GISMAP_ERR, GOOGLE_GISMAP_RSP, GOOGLE_GISMAP_DEF, dwDefTime);
	CItilGroup oGaodeItilGroup(GAODE_GISMAP_REQ, GAODE_GISMAP_ERR, GAODE_GISMAP_RSP, GAODE_GISMAP_DEF, dwDefTime);
	
	switch (dwApiType)
	{
		case E_GISMAP_API_SOSO:
			m_ddwKey          = E_GISMAP_API_SOSO;  
			m_dwReqCmd        = GISMAPGATEWAYAO_GETSOSOCOORDINATES_REQ_CMD_ID;
			m_dwRspCmd        = GISMAPGATEWAYAO_GETSOSOCOORDINATES_RESP_CMD_ID;
			m_strProtocolName = "##CSosoGatewayAsynProtocol";
			m_vecItilGroup.push_back(oSosoItilGroup);
			break;
			
		case E_GISMAP_API_SOSO2:
			m_ddwKey          = E_GISMAP_API_SOSO2;  
			m_dwReqCmd        = GISMAPGATEWAYAO_GETSOSO2COORDINATES_REQ_CMD_ID;
			m_dwRspCmd        = GISMAPGATEWAYAO_GETSOSO2COORDINATES_RESP_CMD_ID;
			m_strProtocolName = "##CSoso2GatewayAsynProtocol";
			m_vecItilGroup.push_back(oSoso2ItilGroup);
			break;
			
		case E_GISMAP_API_ALIYUN:
			m_ddwKey          = E_GISMAP_API_ALIYUN;  
			m_dwReqCmd        = GISMAPGATEWAYAO_GETALIYUNCOORDINATES_REQ_CMD_ID;
			m_dwRspCmd        = GISMAPGATEWAYAO_GETALIYUNCOORDINATES_RESP_CMD_ID;
			m_strProtocolName = "##CAliyunGatewayAsynProtocol";
			m_vecItilGroup.push_back(oSosoItilGroup);
			break;
			
		case E_GISMAP_API_BAIDU:
			m_ddwKey          = E_GISMAP_API_BAIDU;  
			m_dwReqCmd        = GISMAPGATEWAYAO_GETBAIDUCOORDINATES_REQ_CMD_ID;
			m_dwRspCmd        = GISMAPGATEWAYAO_GETBAIDUCOORDINATES_RESP_CMD_ID;
			m_strProtocolName = "##CBaiduGatewayAsynProtocol";
			m_vecItilGroup.push_back(oBaiduItilGroup);
			break;
			
		case E_GISMAP_API_GOOGLE:
			m_ddwKey          = E_GISMAP_API_GOOGLE;  
			m_dwReqCmd        = GISMAPGATEWAYAO_GETGOOGLECOORDINATES_REQ_CMD_ID;
			m_dwRspCmd        = GISMAPGATEWAYAO_GETGOOGLECOORDINATES_RESP_CMD_ID;
			m_strProtocolName = "##CGoogleGatewayAsynProtocol";
			m_vecItilGroup.push_back(oGoogleItilGroup);
			break;
			
		case E_GISMAP_API_GAODE:
			m_ddwKey          = E_GISMAP_API_GAODE;  
			m_dwReqCmd        = GISMAPGATEWAYAO_GETGAODECOORDINATES_REQ_CMD_ID;
			m_dwRspCmd        = GISMAPGATEWAYAO_GETGAODECOORDINATES_RESP_CMD_ID;
			m_strProtocolName = "##CGaodeGatewayAsynProtocol";
			m_vecItilGroup.push_back(oGaodeItilGroup);
			break;
			
		default:
			break;
	}
}

CGisMapGatewayAsynProtocol::~CGisMapGatewayAsynProtocol(){}

uint32_t CGisMapGatewayAsynProtocol::Send(
		const CCntlInfo& rCntlInfo,
		const std::string& strMachineKey,
		const std::string& strSource,
		uint32_t dwSceneId,
		const CAsynSendParamBo& oAsynSendParamBo,
		const std::string& strInReserve,
		erp::gis::ao::CLiber& oLiber)
{
	uint32_t iRetCode = 0;
	std::set<uint32_t> setMapApiType;
	CCoordinatesQueryPo oCoordinateQueryPo;
	oAsynSendParamBo.GetRequestApiType(setMapApiType);
	oAsynSendParamBo.GetCoordinateQueryPo(oCoordinateQueryPo);

	if (setMapApiType.find(m_dwExtType) == setMapApiType.end())
	{
		// ignore this request.
		return 0;
	}
	
	if(IsOpen(oLiber))
	{
		iRetCode = SendGetCoordinate(
					rCntlInfo, 
					strMachineKey, 
					__FILE__, 
					dwSceneId, 
					oAsynSendParamBo, 
					strInReserve);
		iRetCode = oLiber.Checkin(m_dwRspCmd, Check(iRetCode));
		if(iRetCode!=0)
		{
			C2C_WW_LOG_FERR(iRetCode, "%s SendGetCoordinates Failed AddressText:%s", 
				m_strProtocolName.c_str(), oCoordinateQueryPo.GetDestAddrDetail().c_str());
		}
		else
		{
			C2C_WW_LOG("%s SendGetCoordinates Passed AddressText:%s", 
				m_strProtocolName.c_str(), oCoordinateQueryPo.GetDestAddrDetail().c_str());
		}
	}
	else
	{
		C2C_WW_LOG("%s SendGetCoordinates Closed AddressText:%s", 
			m_strProtocolName.c_str(), oCoordinateQueryPo.GetDestAddrDetail().c_str());
	}
	return iRetCode;
}

uint32_t CGisMapGatewayAsynProtocol::Receive(
		const CAsynSendParamBo& oAsynSendParamBo,
		const uint32_t dwChannel,
		CCmdObj& oCmd,
		CAsynRecvResultBo& oAsynRecvResultBo,
		std::string& strErrMsg,
		std::string& strOutReserve,
		erp::gis::ao::CLiber& oLiber,
		c2cent::library::wtimeelf::CWTimeElfItil &oWTimeElf)
{
	uint32_t iRetCode = 0;
	std::set<uint32_t> setMapApiType;
	CCoordinatesQueryPo oCoordinateQueryPo;
	oAsynSendParamBo.GetRequestApiType(setMapApiType);
	oAsynSendParamBo.GetCoordinateQueryPo(oCoordinateQueryPo);
	
	if (setMapApiType.find(m_dwExtType) == setMapApiType.end())
	{
		// ignore this request.
		C2C_WW_LOG("No Match, Ignore this request");
		return 0;
	}
		
	iRetCode = ReceiveCoordinate(oCmd, oAsynRecvResultBo, strErrMsg, strOutReserve);
	iRetCode = oLiber.Checkout(m_dwRspCmd, Check(iRetCode));
	oWTimeElf.GetTimeMarkT(m_strProtocolName.c_str(), iRetCode, &m_vecItilGroup[dwChannel%m_vecItilGroup.size()]);
	if(iRetCode!=0)
	{
		// for loging.
		CCntlInfo   rCntlInfo;
		std::string strMachineKey = __FUNCTION__;
		std::string strSource     = __FILE__;
		C2C_WW_LOG_FERR(iRetCode,"%s ReceiveGetCoordinate Failed CmdId:%u AddressText:%s", 
			m_strProtocolName.c_str(), oCmd.getCmdId(), oCoordinateQueryPo.GetDestAddrDetail().c_str());
		return 0;
	}	
	C2C_WW_LOG("%s ReceiveGetCoordinate Passed CmdId:%u AddressText:%s", 
		m_strProtocolName.c_str(), oCmd.getCmdId(), oCoordinateQueryPo.GetDestAddrDetail().c_str());
	
	return 0;
}

bool CGisMapGatewayAsynProtocol::CheckCustormRetCode(int32_t iRetCode)
{
	if (0 != iRetCode)
	{
		return false;
	}

	return true;
}

uint32_t CGisMapGatewayAsynProtocol::IsOpen(
		const erp::gis::ao::CLiber& oLiber)
{
	if(m_bOpen)
	{
		if(m_dwCloseTime + m_dwCloseDuration > oLiber.GetTimeNow())
		{
			return false;
		}
		return true;
	}
	return false;
}

uint32_t CGisMapGatewayAsynProtocol::SendGetCoordinate(
		const CCntlInfo& rCntlInfo,
		const std::string& strMachineKey,
		const std::string& strSource,
		uint32_t dwSceneId,
		const CAsynSendParamBo& oAsynSendParamBo,
		const std::string& strInReserve)
{
	CCoordinatesQueryPo oCoordinateQueryPo;
	oAsynSendParamBo.GetCoordinateQueryPo(oCoordinateQueryPo);
	
	switch (m_dwExtType)
	{
		case E_GISMAP_API_SOSO:
			return m_oStub.SendGetSosoCoordinates(
				rCntlInfo, strMachineKey, strSource, dwSceneId, oCoordinateQueryPo, strInReserve);
		case E_GISMAP_API_SOSO2:
			return m_oStub.SendGetSoso2Coordinates(
				rCntlInfo, strMachineKey, strSource, dwSceneId, oCoordinateQueryPo, strInReserve);
		case E_GISMAP_API_ALIYUN:
			return m_oStub.SendGetAliyunCoordinates(
				rCntlInfo, strMachineKey, strSource, dwSceneId, oCoordinateQueryPo, strInReserve);
		case E_GISMAP_API_BAIDU:
			return m_oStub.SendGetBaiduCoordinates(
				rCntlInfo, strMachineKey, strSource, dwSceneId, oCoordinateQueryPo, strInReserve);
		case E_GISMAP_API_GOOGLE:
			return m_oStub.SendGetGoogleCoordinates(
				rCntlInfo, strMachineKey, strSource, dwSceneId, oCoordinateQueryPo, strInReserve);
		case E_GISMAP_API_GAODE:
			return m_oStub.SendGetGaodeCoordinates(
				rCntlInfo, strMachineKey, strSource, dwSceneId, oCoordinateQueryPo, strInReserve);
		default:
			return -1;
			
	}
}

uint32_t CGisMapGatewayAsynProtocol::ReceiveCoordinate(
		CCmdObj& oCmd,
		CAsynRecvResultBo& oAsynRecvResultBo,
		std::string& strErrMsg,
		std::string& strOutReserve)
{
	uint32_t iRetCode = 0;
	std::vector<erp::gis::po::CCoordinatesPo> vecCoordinatesPo;
	switch (m_dwExtType)
	{
		case E_GISMAP_API_SOSO:
			iRetCode = m_oStub.RecvGetSosoCoordinates(oCmd, vecCoordinatesPo, strErrMsg, strOutReserve);
			break;
		case E_GISMAP_API_SOSO2:
			iRetCode =  m_oStub.RecvGetSoso2Coordinates(oCmd, vecCoordinatesPo, strErrMsg, strOutReserve);
			break;
		case E_GISMAP_API_ALIYUN:
			iRetCode = m_oStub.RecvGetAliyunCoordinates(oCmd, vecCoordinatesPo, strErrMsg, strOutReserve);
			break;
		case E_GISMAP_API_BAIDU:
			iRetCode = m_oStub.RecvGetBaiduCoordinates(oCmd, vecCoordinatesPo, strErrMsg, strOutReserve);
			break;
		case E_GISMAP_API_GOOGLE:
			iRetCode = m_oStub.RecvGetGoogleCoordinates(oCmd, vecCoordinatesPo, strErrMsg, strOutReserve);
			break;
		case E_GISMAP_API_GAODE:
			iRetCode = m_oStub.RecvGetGaodeCoordinates(oCmd, vecCoordinatesPo, strErrMsg, strOutReserve);
			break;
		default:
			return -1;
			
	}
	if (iRetCode != 0)
	{
		strErrMsg = m_oStub.GetLastErrMsg();
		oAsynRecvResultBo.AddApiMapResponseErr(m_dwExtType, iRetCode);
		return iRetCode;
	}

	oAsynRecvResultBo.AddCoordiantes(m_dwExtType, vecCoordinatesPo);
	return 0;
}


